<?php
namespace app\common\model;
use think\Model;
use think\facade\Cache;
use think\facade\Db;
use base\pay\WxApi;
use base\other\Strings;

/**
 * TODO 店铺提现
 * Class UserExtract
 * @package app\models\user
 */
class ShopExtract  extends Model
{
	// 自动完成
	protected $insert = ['extract_no'];
	protected function setExtractNoAttr() {
		return Strings::createOrderNo('tx');
    }
	
    //审核中
    const AUDIT_STATUS = 0;
    //未通过
    const FAIL_STATUS = -1;
    //已提现
    const SUCCESS_STATUS = 1;
	//--
    protected static $extractType = ['alipay','bank','wx'];
    protected static $extractTypeMsg = [
    	'alipay'=>'支付宝',
    	'bank'=>'银行卡',
    	'wx'=>'微信'
    ];
    protected static $status = array(
        -1=>'未通过',
        0 =>'审核中',
        1 =>'已提现'
    );
	
	/**
    * 错误信息
    */
	public $errorInfo;
	
    /**
     * 用户自主提现记录,后台执行审核
     * @param array $userInfo 用户个人信息
     * @param array $data 提现详细信息
     * @return bool
     */
    public  function shopExtract($shopId,$data,$type='balance'){
		//获取参数
    	list($extractType,$extractPrice,$extractName,$extractCode,$bankCode,$bankName)= [
    		$data['extract_type'] ?: '',
    		$data['extract_price'] ?: 0,
    		$data['extract_name'] ?: '',
    		$data['extract_code'] ?: '',
    		$data['bank_code'] ?: '',
    		$data['bank_name'] ?: ''
    	];
		
		if(empty($extractType) || empty($extractPrice)) {
        	throw new \think\Exception('必填参数项错误！');
        }
        if(!in_array($extractType,self::$extractType)){
        	throw new \think\Exception('提现方式不存在！');
        }
		if($extractType == 'alipay' && (empty($extractName) || empty($extractCode)) ) {
		  	throw new \think\Exception('必填参数项错误！');
        }
        
        $bankCode = $this->getBankCode($bankName);
		if($extractType == 'bank' && (empty($extractName) || empty($extractCode) || empty($bankCode))) {
        	throw new \think\Exception('必填参数项错误！');
        }
        
        $shopInfo = model('shop')->get($shopId);
		$minWithdraw = (float)getSystem('buess_shop_extract_min');
		$withdrawCost = (float)getSystem('buess_shop_extract_cost');
		$accountMoney = $shopInfo[$type];
        if($accountMoney < 0 || $extractPrice > $accountMoney) {
		  	throw new \think\Exception('账户余额不足'.$extractPrice);
        }
		
		//手续费
		$proceduresCost = ($withdrawCost / 100) * $extractPrice;
		if($extractPrice < ($minWithdraw ?? 1)) {
			throw new \think\Exception('提现金额必须大于等于 '.($minWithdraw ?: 1));
        }
	
        $balance = bcsub($accountMoney,$extractPrice,2);
		$balance = $balance < 0 ? 0 : $balance;
        $insertData = [
            'shop_id' => $shopInfo['id'],
            'money_type' => $type,
            'extract_type' => $extractType,
            'extract_price' => $extractPrice,
            'extract_code'=> $extractCode ?: $shopInfo['bank_code'],
            'extract_name'=> $extractName ?: $shopInfo['bank_name'],
            'bank_code'=> $bankCode,
            'bank_name'=> $bankName,
            'balance' => $balance,
            'procedures_price'=> $proceduresCost,
            'status' => self::AUDIT_STATUS
        ];
		
        if($extractType == 'alipay'){
            $mark = '提现到支付宝'.$extractPrice.'元,手续费'.$proceduresCost.'元';
        }else if($extractType== 'bank'){
            $mark = '提现到银联卡('.$insertData['extract_code'].') '.$extractPrice.'元,手续费'.$proceduresCost.'元';
        }else if($data['extract_type'] == 'wx'){
            $mark = '提现到微信提现'.$extractPrice.'元,手续费'.$proceduresCost.'元';
        }
		
        \Db::startTrans();
        try{
            $res1 = self::create($insertData);
            if(!$res1) {
            	\Db::rollback();
            	throw new \think\Exception('异常错误！');
            }
            $res2 = model('Shop')->where("id",$shopInfo['id'])->update([$type=>$balance]);
            $res3 = model('ShopBill')->expend('提现',$shopInfo['id'],$type,'extract',$extractPrice,$res1['extract_no'],$balance,$mark);
            $res = $res2 && $res3;
            if(!$res){
                \Db::rollback();
				throw new \think\Exception('异常错误！');
            }
            \Db::commit();
            return	true;
        }catch (\Exception $e){
            \Db::rollback();
			throw new \think\Exception($e->getMessage());
        }
    }
	
	 /**
     * 驳回
     * @param $openid
     * @return mixed
     */
    public function reject($id,$desc,$type='balance')
    {
        $extract = self::get($id);
		if($extract['status'] != 0){
  			throw new \think\Exception('状态错误！');
		}
		
		$shopId = $extract['shop_id'];
		
		\Db::startTrans();
        try{
        	
        	$extract -> status_desc = $desc;
			$extract -> status_time = date("Y-m-d H:i:s");
			$extract -> status = -1;
	        if( !$extract -> save() ) {
	        	\Db::rollback();
	    		throw new \think\Exception('异常错误！');
	        }
			
			$extractPrice = $extract['extract_price'];
			$accountMoney = model('Shop')->where('id',$shopId)->value($type);
			$balance = bcadd($accountMoney,$extractPrice,2);
			$type = $extract['money_type'];
			$res2 = model('Shop')->where("id",$shopId)->update([$type=>$balance]);
			$res3 =model('ShopBill')->where('link_id',$extract['extract_no'])->update(['status'=>'-1']);
        	$res4 = model('ShopBill')->income('提现驳回',$shopId,$type,'extract_reject',$extractPrice,$extract['extract_no'],$balance,'提现被驳回',0,'-1');
            $res = $res2 && $res3 && $res4;
            if(!$res){
                \Db::rollback();
				throw new \think\Exception('异常错误！');
            }
			
            \Db::commit();
            return	true;
			
        }catch (\Exception $e){
            \Db::rollback();
			throw new \think\Exception($e->getMessage());
        }
    }
	
	/**
     * 获得用户提现总金额
     * @param $bankName
     * @return mixed
     */
    public static function getBankCode($bankName){
    	$code = '';
		switch($bankName){
		    case '工商银行': $code =  1002;  break;
		    case '农业银行': $code =  1005;  break;
		    case '建设银行': $code =  1003;  break;
		    case '中国银行': $code =  1026;  break;
		    case '交通银行': $code =  1020;  break;
		    case '招商银行': $code =  1001;  break;
		    case '邮储银行': $code =  1066;  break;
		    case '民生银行': $code =  1006;  break;
		    case '平安银行': $code =  1010;  break;
		    case '中信银行': $code =  1021;  break;
		    case '浦发银行': $code =  1004;  break;
		    case '兴业银行': $code =  1009;  break;
		    case '光大银行': $code =  1022;  break;
		    case '广发银行': $code =  1027;  break;
		    case '华夏银行': $code =  1025;  break;
		    case '宁波银行': $code =  1056;  break;
		    case '北京银行': $code =  4836;  break;
		    case '上海银行': $code =  1024;  break;
		    case '南京银行': $code =  1054;  break;
		    case '长子县融汇村镇银行': $code =  4755;  break;
		    case '长沙银行': $code =  4216;  break;
		    case '浙江泰隆商业银行': $code =   4051;  break;
		    case '中原银行': $code =  4753;  break;
		    case '企业银行（中国）': $code =   4761;  break;
		    case '顺德农商银行': $code =  4036;  break;
		    case '衡水银行': $code =   4752;  break;
		    case '长治银行': $code =   4756;  break;
		    case '大同银行': $code =   4767;  break;
		    case '河南省农村信用社': $code =  4115;  break;
		    case '宁夏黄河农村商业银行': $code =  4150;  break;
		    case '山西省农村信用社': $code =  4156;  break;
		    case '安徽省农村信用社': $code =  4166;  break;
		    case '甘肃省农村信用社': $code =  4157;  break;
		    case '天津农村商业银行': $code =  4153;  break;
		    case '广西壮族自治区农村信用社': $code =  4113;  break;
		    case '陕西省农村信用社': $code =  4108;  break;
		    case '深圳农村商业银行': $code =  4076;  break;
		    case '宁波鄞州农村商业银行': $code =  4052;  break;
		    case '浙江省农村信用社联合社': $code =  4764;  break;
		    case '江苏省农村信用社联合社': $code =  4217;  break;
		    case '江苏紫金农村商业银行股份有限公司': $code =  4072;  break;
		    case '北京中关村银行股份有限公司': $code =  4769;  break;
		    case '星展银行（中国）有限公司': $code =  4778;  break;
		    case '枣庄银行股份有限公司': $code = 4766;  break;
		    case '海口联合农村商业银行股份有限公司': $code =  4758;  break;
		    case '南洋商业银行（中国）有限公司': $code =  4763;  break;
		}
		return $code;
	}
	
	/**
     * 确认
     * @param $openid
     * @return mixed
     */
    public function confirm($id)
    {
        $extract = self::get($id);
		if($extract['status'] != 0){
  			throw new \think\Exception('状态错误！');
		}
		
		$minWithdraw = (float)getSystem('buess_shop_extract_min');
		if($extract['extract_price'] < ($minWithdraw ?: 0 )){
  			throw new \think\Exception('未达到最低提现：'.($minWithdraw ?: 0));
		}
		
		$shopId = $extract['shop_id'];
		$uid = model('Shop')->where('id',$shopId)->value('uid');
		$no = $extract['extract_no'];
		$name = $extract['extract_name'];
		$price = $extract['extract_price'] - $extract['procedures_price'];
		$bankCode = $extract['bank_code'];
		$bankName = $extract['bank_name'];
		$extractType = $extract['extract_type'];
		
		\Db::startTrans();
        try{
        	
        	$extract -> status_time = date("Y-m-d H:i:s");
			$extract -> status = 1;
            $res = $extract -> save();
	        if (!$res ) {
	        	\Db::rollback();
	  			throw new \think\Exception( '失败！');
	        }
			
			$isAutoWithdraw= (float)getSystem('buess_shop_extract_is_auto');
			if($isAutoWithdraw==1){
				if($extractType == 'wx'){
					$openid = model('user')->where('id',$uid)->value('openid');
					$res = WxApi::withdrawal($openid,$no,$name,$price,'提现到微信',"wx_app");
				}
				if($extractType == 'bank'){
					$desc = '提现到银行卡';
					$res = WxApi::withdrawalBank($no,$name,$price,$bankCode,$bankName,$desc);
				}
				if($extractType == 'alipay'){
					\Db::rollback();
	  				throw new \think\Exception('线上支付宝提现，功能未实现！');
				}
			}
	
            if(!$res){
                \Db::rollback();
	  			throw new \think\Exception('失败！');
            }
			
            \Db::commit();
            return	true;
			
        }catch (\Exception $e){
            \Db::rollback();
            throw new \think\Exception($e->getMessage());
        }
    }

    /**
     * 获得用户最后一次提现信息
     * @param $openid
     * @return mixed
     */
    public static function userLastInfo($id)
    {
        return self::where('shop_id',$id)->order('add_time DESC')->find();
    }

    /**
     * 获得用户提现总金额
     * @param $uid
     * @return mixed
     */
    public static function userExtractTotalPrice($id)
    {
        return self::where('shop_id',$id)->value('SUM(extract_price)')?:0;
    }

    /**
     * 用户提现记录列表
     * @param int $uid 用户uid
     * @param int $first 截取行数
     * @param int $limit 截取数
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function extractList($id,$first = 0,$limit = 20)
    {
        return self::where('shop_id',$id)->order('add_time desc')->page($first,$limit)->select();
    }

    /**
     * 获取累计已提现佣金
     * @param $uid
     * @return float
     */
    public static function extractSum($id)
    {
        return self::where('shop_id',$id)->where('status',1)->sum('extract_price');
    }

}